# 装饰器：
# 遵循开放封闭原则，在不改变原函数的情况下，扩展了函数的功能
# 定义
# def xxx(func):
#  def xxx(参数,...):
#      func()
#      ...
#  return xxx

# 使用
# @xxx
# def xxx():
#      ...

# 装饰器功能：
# 1.引入日志
# 2.函数执行时间统计
# 3.执行函数前预备处理
# 4.执行函数后清理功能
# 5.权限校验
# 6.缓存

def foo():
    print('foo函数执行了')

def func():
    print('func函数执行了')

# foo()
foo = func
foo()
print('----------------------------')

def decorator(func):
    print('---------->1')
    def wrapper():
        func()
        print('刷漆')
        print('贴壁纸')
        print('铺地板')
    print('---------->2')
    return wrapper

@decorator # house = decorator(house)
def house():
    print('装修房子')

house()
print('----------------------------')
def decorator(func):
    def wrapper(*args):# args是一个元组
        func(*args) # func()就是house()
        print('刷漆')
        print('贴壁纸')
        print('铺地板')
    return wrapper

@decorator # house = decorator(house)
def house(address):
    print('房子的地址在:{}是一个毛呸房...'.format(address))
@decorator
def changfang(address,arga):
    print('房子的地址在:{}是一个毛呸房,建筑面积是：{}平米'.format(address,arga))

house('北京四合院') # house就是wrapper
print('----------------------------')
changfang('北京四合院',1000) # changfang就是wrapper
print('----------------------------')

'''
装饰器修饰有返回值函数
原函数有返回值，装饰器的内部函数也要有返回值
'''

def decorator(func):
    def wrapper(*args,**kwargs):# args是一个元组 kwargs是一个字典
        r = func(*args,**kwargs) # func()就是house()
        print('预计装修费用:{}'.format(r))
        print('刷漆')
        print('贴壁纸')
        print('铺地板')
        return 60000
    return wrapper

@decorator
def house():
    print('我是一个毛呸房')
    return 50000

r = house() # house就是wrapper
print(r)
print('----------------------------')

def outer_check(time):
    print('---------->1')
    def check_time(action):
        print('---------->3')
        def do_action():
            if time < 22:
                return action()
            else:
                return '对不起，您不具有该权限'
        print('---------->4')
        return do_action
    print('---------->2')
    return check_time

@outer_check(23)
def play_game():
    return '玩游戏'

print(play_game())















